﻿using System;
using System.Windows.Interop;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows;

namespace Faust.Andrew.MTG.Helper
{
    public class CursorHelper
    {
        private struct IconInfo
        {
            public bool fIcon;
            public int xHotspot;
            public int yHotspot;
            public IntPtr hbmMask;
            public IntPtr hbmColor;
        }

        [DllImport("user32.dll")]
        private static extern IntPtr CreateIconIndirect(ref IconInfo icon);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);


        private static Cursor InternalCreateCursor(System.Drawing.Bitmap bmp,
            int xHotSpot, int yHotSpot)
        {
            IconInfo tmp = new IconInfo();
            GetIconInfo(bmp.GetHicon(), ref tmp);
            tmp.xHotspot = xHotSpot;
            tmp.yHotspot = yHotSpot;
            tmp.fIcon = false;

            IntPtr ptr = CreateIconIndirect(ref tmp);
            SafeFileHandle handle = new SafeFileHandle(ptr, true);
            return CursorInteropHelper.Create(handle);
        }


        public static Cursor CreateCursor(FrameworkElement element, double zoomLevel, double rotation)
        {
            //Rotation isn't currently used. I would like to make it rotate the image to match the local play space,
            //but haven't figured out a good way to do it yet.
            RenderTargetBitmap rtb = element.ToBitmapSource().Zoom(zoomLevel);

            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(rtb));

            MemoryStream ms = new MemoryStream();
            encoder.Save(ms);

            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms);

            ms.Close();
            ms.Dispose();

            Point hotSpot = new Point(0, 0);

            Cursor cur = InternalCreateCursor(bmp, (int)hotSpot.X, (int)hotSpot.Y);

            bmp.Dispose();

            return cur;
        }

    }
}
